import cv2
import numpy as np


def calculate_slider_offset(background_path, slider_path, threshold=0.8):
    """
    计算滑块需要移动的距离（偏移量）
    :param background_path: 带缺口的背景图路径
    :param slider_path: 滑块图路径（透明背景）
    :param threshold: 匹配阈值，越高越严格
    :return: 滑块需要移动的水平距离（像素），未找到返回0
    """
    # 读取背景图和滑块图（注意滑块图保留透明通道）
    background = cv2.imread(background_path, cv2.IMREAD_COLOR)
    slider = cv2.imread(slider_path, cv2.IMREAD_UNCHANGED)  # 读取透明通道

    if background is None or slider is None:
        raise FileNotFoundError("背景图或滑块图不存在，请检查路径")

    # 分离滑块的透明通道（alpha通道）作为掩码
    slider_gray = cv2.cvtColor(slider[:, :, :3], cv2.COLOR_BGR2GRAY)  # 滑块转为灰度图
    slider_mask = slider[:, :, 3]  # 透明通道作为掩码（非透明区域为滑块有效区域）

    # 背景图转为灰度图（减少计算量）
    background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY)

    # 使用模板匹配寻找滑块在背景中的位置（匹配滑块缺口）
    # TM_CCOEFF_NORMED：归一化相关系数匹配，结果越接近1越匹配
    result = cv2.matchTemplate(
        image=background_gray,
        templ=slider_gray,
        method=cv2.TM_CCOEFF_NORMED,
        mask=slider_mask  # 只匹配滑块有效区域
    )

    # 找到匹配度超过阈值的位置
    locations = np.where(result >= threshold)
    if len(locations[0]) == 0:
        print("未找到匹配的缺口位置，可能需要调整阈值")
        return 0

    # 取最匹配的位置（第一个匹配点）
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    top_left = max_loc  # 匹配区域的左上角坐标

    # 滑块需要移动的距离：缺口左上角x坐标（通常滑块初始位置在左侧，直接用x坐标即可）
    offset = top_left[0]

    # 可视化匹配结果（可选，用于调试）
    h, w = slider_gray.shape[:2]
    cv2.rectangle(background, top_left, (top_left[0] + w, top_left[1] + h), (0, 255, 0), 2)
    cv2.imwrite("match_result.png", background)
    print(f"匹配结果已保存为 match_result.png，偏移量：{offset} 像素")

    return offset


if __name__ == "__main__":
    # 示例：替换为你的图片路径
    background_img = "background.png"  # 带缺口的背景图
    slider_img = "slider.png"  # 滑块图（透明背景）

    try:
        distance = calculate_slider_offset(background_img, slider_img)
        print(f"滑块需要移动的距离：{distance} 像素")
    except Exception as e:
        print(f"错误：{e}")